﻿#include "GUIGeometryMirrorDialog.h"
#include "ui_GUIGeometryMirrorDialog.h"

#include "FITK_Interface/FITKInterfaceGeometry/FITKGeoInterfaceFactory.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeomTools.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoTransformation.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKGeoCommandList.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsVirtualTopo.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKCore/FITKActionOperator.h"
#include "FITK_Kernel/FITKCore/FITKDataRepo.h"
#include "PickDataProvider/PickedDataProvider.h"
#include "PickDataProvider/PickedData.h"
#include <QMessageBox>

namespace GUI {
    GUIGeometryMirrorDialog::GUIGeometryMirrorDialog(Interface::FITKAbsGeoCommand* obj,Core::FITKActionOperator* oper, QWidget* parent)
        :Core::FITKDialog(parent), _oper(oper),_obj(obj)
    {
        _ui = new Ui::GUIGeometryMirrorDialog();
        _ui->setupUi(this);
        // 设置对话框关闭时自动删除
        setAttribute(Qt::WA_DeleteOnClose);
        //去掉问号
        Qt::WindowFlags flags = windowFlags();
        flags &= ~Qt::WindowContextHelpButtonHint;
        setWindowFlags(flags);
        if (!_obj)
        {
            _isCreate = true;
            setWindowTitle(tr("Create Mirror"));
        }
        else
        {
            setWindowTitle(tr("Edit Mirror"));
        }
        //获取拾取器，绑定拾取结束信号
        GraphData::PickedDataProvider* pickProvider = GraphData::PickedDataProvider::getInstance();
        //清除拾取对象所有的连接
        if (pickProvider != nullptr)
        {
            connect(pickProvider, &GraphData::PickedDataProvider::sigDataPicked, this, &GUIGeometryMirrorDialog::pickFinishedOper);
        }
        this->init();
    }

    GUIGeometryMirrorDialog::~GUIGeometryMirrorDialog()
    {
        if (_ui) {
            delete _ui;
            _ui = nullptr;
        }
        //所有的类在执行完毕后，将清空对3维的操作
        GraphData::PickedDataProvider* pickProvider = GraphData::PickedDataProvider::getInstance();
        if (!pickProvider) return;
        pickProvider->clearPickedData();
        ////拾取对象 关闭
        ////拾取方式 空
        enablePickSig(GUI::GUIPickInfo::PickObjType::POBNone, GUI::GUIPickInfo::PickMethod::PMNone);
    }

    void GUIGeometryMirrorDialog::init()
    {
        //获取几何管理器
        _geometryData = FITKAPP->getGlobalData()->getGeometryData<Interface::FITKGeoCommandList>();
        if (_geometryData == nullptr) return;

        if (_isCreate)
        {
            QString name = _geometryData->checkName(tr("Mirror-1"));
            _ui->lineEdit_Name->setText(name);
        }
        else
        {

        }
    }

    void GUIGeometryMirrorDialog::pickFinishedOper()
    {
        //获取拾取数据
        GraphData::PickedDataProvider* pickProvider = GraphData::PickedDataProvider::getInstance();
        if (!pickProvider) return;
        QList<GraphData::PickedData*> pickList = pickProvider->getPickedList();
        QList<Interface::VirtualShape> virtualShape;
        for (GraphData::PickedData* pickData : pickList) {
            if (pickData == nullptr)continue;
            int cmdID = pickData->getPickedDataObjId();
            QHash<int, int>OtherIDs = pickData->getPickedOtherIDs();//key PickedId  value index
            for (GraphData::PickDataInfo i : pickData->getPickOtherInfos())
            {
                if (OtherIDs.contains(i._id) == true)
                {
                    //添加拾取数据
                    Interface::VirtualShape temp(cmdID, i._id, OtherIDs.value(i._id));
                    virtualShape.push_back(temp);
                }
            }
        }
        if (_pickFlag == PickFlag::Target)
        {
            if (virtualShape.size() == 0)
            {
                _ui->label_Num->setText(tr("Picked (0)"));
                _virtualTarget.reset();
            }
            else
            {
                _virtualTarget = virtualShape.at(0);
                _virtualTarget.Type = Interface::FITKGeoEnum::VTopoShapeType::VSSolid;
                _ui->label_Num->setText(tr("Picked (1)"));
            }
        }
        else if (_pickFlag == PickFlag::Tool)
        {
            if (virtualShape.size() == 0)
            {
                _ui->label_Num_2->setText(tr("Picked (0)"));
                _virtualTool.reset();
            }
            else
            {
                _virtualTool = virtualShape.at(0);
                _virtualTool.Type = Interface::FITKGeoEnum::VTopoShapeType::VSFace;
                _ui->label_Num_2->setText(tr("Picked (1)"));
            }
        }
    }

    void GUIGeometryMirrorDialog::getDataFormWidget()
    {
        Interface::FITKAbsGeoModelMirror *mirrorOper = dynamic_cast<Interface::FITKAbsGeoModelMirror *>(_obj);
        if (mirrorOper == nullptr) return;
        mirrorOper->setSourceShape(_virtualTarget);
        mirrorOper->setReference(_virtualTool);
        if (_ui->checkBox->isChecked())
            mirrorOper->setCopy(false);
        else
        {
            mirrorOper->setCopy(true);
            mirrorOper->addReferenceCmdID(_virtualTarget.CmdId);
        }
        _objID = mirrorOper->getDataObjectID();
    }

    bool GUIGeometryMirrorDialog::createObjData()
    {
        if (!_geometryData) return false;
        if (!editObjData())return false;
        _geometryData->appendDataObj(_obj);
        return true;
    }

    bool GUIGeometryMirrorDialog::editObjData()
    {
        if (!_oper || !_obj || !_geometryData) return false;
        //设置名称
        _obj->setDataObjectName(_ui->lineEdit_Name->text());
        //设置界面数据
        this->getDataFormWidget();
        if (_obj->update() == false)
        {
            //创建失败不将该数据append
            QMessageBox::warning(this, "", tr("The geometry could not be created properly").arg(_ui->lineEdit_Name->text()), QMessageBox::Ok);
            return false;
        }
        _oper->setArgs("objID", _objID);
        return true;
    }

    void GUIGeometryMirrorDialog::on_pushButton_OK_clicked()
    {
        if (!_geometryData) return ;
        //获取数据名称
        QString name = _ui->lineEdit_Name->text();
        if (_geometryData->getDataByName(name)) {
            QMessageBox::warning(this, "", tr("\"%1\" already exists and cannot be overwritten.").arg(name), QMessageBox::Ok);
            return ;
        }
        if (_virtualTarget.isNull())
        {
            QMessageBox::warning(this, "", tr("Pick up the target model first.").arg(name), QMessageBox::Ok);
            return;
        }
        if (_virtualTool.isNull())
        {
            QMessageBox::warning(this, "", tr("Pick up the tool model first.").arg(name), QMessageBox::Ok);
            return;
        }
        //创建动作
        if (_isCreate)
        {
            Interface::FITKInterfaceGeometryFactory* geoFactory = Interface::FITKInterfaceGeometryFactory::getInstance();
            if (!geoFactory) return;
            _obj = geoFactory->createCommand(Interface::FITKGeoEnum::FITKGeometryComType::FGTMirror);
            if (!_obj) return;
            if (!this->createObjData())
                return;
            _oper->execProfession();
        }
        //修改动作
        else
        {
            if (!this->editObjData())
                return;
            _oper->execProfession();
        }
        this->accept();
    }

    void GUIGeometryMirrorDialog::on_pushButton_Cancel_clicked()
    {
        //关闭窗口
        _oper->setArgs("objID", -1);
        if (_isCreate) {
            //删除对象
            if (_obj) delete _obj;
            _obj = nullptr;
        }
        this->reject();
    }

    void GUIGeometryMirrorDialog::on_Target_pick_clicked()
    {
        //设置拾取方式
        _pickFlag = PickFlag::Target;
        enablePickSig(GUI::GUIPickInfo::PickObjType::POBGeoSolid, GUI::GUIPickInfo::PickMethod::PMSingle);
    }

    void GUIGeometryMirrorDialog::on_Tool_pick_clicked()
    {
        //设置拾取方式
        _pickFlag = PickFlag::Tool;
        enablePickSig(GUI::GUIPickInfo::PickObjType::POBGeoFace, GUI::GUIPickInfo::PickMethod::PMSingle);
    }

    void GUIGeometryMirrorDialog::enablePickSig(GUI::GUIPickInfo::PickObjType objType, GUI::GUIPickInfo::PickMethod methodType)
    {
        GUI::GUIPickInfoStru pickInfo = GUI::GUIPickInfo::GetPickInfo();
        pickInfo._pickObjType = GUI::GUIPickInfo::PickObjType(objType);
        pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod(methodType);
        //设置拾取方式
        GUI::GUIPickInfo::SetPickInfo(pickInfo);
    }
}